package com.xiaobias.a01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;

import java.lang.reflect.Field;
import java.util.Locale;
import java.util.Map;

/**
 * BeanFactory 与 ApplicationContext 的区别
 */
@SpringBootApplication
public class A01Application {
     private static final Logger logger = LoggerFactory.getLogger(A01Application.class);

     public static void main(String[] args) throws Exception{
          ConfigurableApplicationContext context = SpringApplication.run(A01Application.class, args);
          /*
               1. 到底什么是 BeanFactory
                    - 他是 ApplicationContext 的父接口
                    - 他才是 Spring 的核心容器，主要的是 ApplicationContext 实现都【组合】了它的功能
           */
          System.out.println(context);
          /*
               2. BeanFactory 能干点啥
               - 表面上只有 getBean
               - 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各个功能，都由它的实现类提供
           */
          Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
          singletonObjects.setAccessible(true);
          ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
          Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
          map.entrySet().stream().filter(e -> e.getKey().contains("component"))
                  .forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()));

          /*
               3. ApplicationContext 比 BeanFactory 多了点啥
           */
          System.out.println(context.getMessage("hi", null, Locale.CHINA));
          System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
          System.out.println(context.getMessage("hi", null, Locale.JAPAN));

//          Resource[] resources = context.getResources("classpath:application.properties");
          Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
          for (Resource resource : resources) {
               System.out.println(resource);
          }

          System.out.println(context.getEnvironment().getProperty("java_home"));
          System.out.println(context.getEnvironment().getProperty("server.port"));


//          context.publishEvent(new UserRegisteredEvent(context));
          context.getBean(Component1.class).register();
     }

}
